package com.lcy.execudeCode.service;

import cn.hutool.json.JSONUtil;
import com.lcy.codesandbox.CodeSandBox;
import com.lcy.codesandbox.model.ExecuteCodeRequest;
import com.lcy.codesandbox.model.ExecuteCodeResponse;
import com.lcy.codesandbox.model.JudgeInfo;
import com.lcy.enums.ProblemJudgeResultEnum;
import com.lcy.enums.ProblemSubmitStatusEnum;
import com.lcy.execudeCode.CodeSandboxManager;
import com.lcy.execudeCode.JudgeService;
import com.lcy.judge.HandleJudgeTask;
import com.lcy.mapper.OjProblemSubmitMapper;
import com.lcy.model.dto.problem.JudgeCase;
import com.lcy.model.entity.OjProblem;
import com.lcy.model.entity.OjProblemSubmit;
import com.lcy.model.judge.JudgeTask;
import com.lcy.service.OjProblemService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class JudgeServiceImpl implements JudgeService {

	@Resource
	private OjProblemService ojProblemService;

	@Resource
	private OjProblemSubmitMapper submitMapper;

	@Value("${codesandbox.type:local}")
	private String type;
	@Transactional
	@Override
	public void doJudge(Long ojProblemSubmitId) throws Exception {

		OjProblemSubmit ojProblemSubmit = submitMapper.selectOneById(ojProblemSubmitId);
		OjProblem ojProblem = ojProblemService.getById(ojProblemSubmit.getQuestionId());

		ExecuteCodeRequest executeCodeRequest = getExecuteCodeRequest(ojProblemSubmit, ojProblem);
		CodeSandBox codeSandbox = CodeSandboxManager.instance(type);
		ojProblemSubmit.setStatus(ProblemSubmitStatusEnum.WAITING.getKey());
		submitMapper.update(ojProblemSubmit);
		ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);
		
		// 确保JudgeInfo不为null，并且包含完整信息
		if (executeCodeResponse.getJudgeInfo() == null) {
			JudgeInfo judgeInfo = new JudgeInfo();
			judgeInfo.setMessage(ProblemJudgeResultEnum.getEnum(ojProblemSubmit.getCodeStatus()) != null ? 
								 ProblemJudgeResultEnum.getEnum(ojProblemSubmit.getCodeStatus()).getValue() : 
								 "代码执行成功");
			judgeInfo.setTime(1L);  // 最小值1ms
			judgeInfo.setMemory(1024L);  // 最小值1KB
			executeCodeResponse.setJudgeInfo(judgeInfo);
		} else {
			JudgeInfo judgeInfo = executeCodeResponse.getJudgeInfo();
			
			// 确保时间和内存值不为0或null
			if (judgeInfo.getTime() == null || judgeInfo.getTime() <= 0) {
				judgeInfo.setTime(1L); // 最小值1ms
			}
			
			if (judgeInfo.getMemory() == null || judgeInfo.getMemory() <= 0) {
				judgeInfo.setMemory(1024L); // 最小值1KB
			}
			
			if (judgeInfo.getMessage() == null) {
				judgeInfo.setMessage("代码执行成功");
			}
			
			log.debug("JudgeInfo 数据: time={}ms, memory={}KB, message={}", 
				judgeInfo.getTime(), judgeInfo.getMemory(), judgeInfo.getMessage());
		}
		
		JudgeTask judgeTask = setJudgeTask(executeCodeResponse, ojProblem, ojProblemSubmit);
		ojProblemSubmit.setStatus(ProblemSubmitStatusEnum.JUDGING.getKey());
		submitMapper.update(ojProblemSubmit);
		
		HandleJudgeTask handleJudgeTask = new HandleJudgeTask();
		ojProblemSubmit.setOutput(JSONUtil.toJsonStr(executeCodeResponse.getOuputList()));
		ojProblemSubmit.setJudgeInfo(JSONUtil.toJsonStr(executeCodeResponse.getJudgeInfo()));
		ojProblemSubmit = handleJudgeTask.doHandle(judgeTask);
		
		// 设置成功状态并保存
		ojProblemSubmit.setStatus(ProblemSubmitStatusEnum.SUCCESS.getKey());
		boolean saveFlag = submitMapper.update(ojProblemSubmit) == 1;
		
		// 更新题目的通过数
		Integer codeStatus = ojProblemSubmit.getCodeStatus();
		if (codeStatus != null && codeStatus.equals(ProblemJudgeResultEnum.ACCEPTED.getKey())) {
			ojProblem.setAcceptedNum(ojProblem.getAcceptedNum() == null ? 1 : ojProblem.getAcceptedNum() + 1);
			ojProblemService.updateById(ojProblem);
		}

		// 添加详细日志
		log.info("判题完成，题目ID: {}, 状态: {}, 代码状态: {}", 
			ojProblemSubmitId,
			ProblemSubmitStatusEnum.getEnum(ojProblemSubmit.getStatus()).getValue(),
			codeStatus != null ? ProblemJudgeResultEnum.getEnum(codeStatus).getValue() : "未知");
		
		if (!saveFlag) {
			throw new Exception("代码提交保存失败");
		}
	}

	private ExecuteCodeRequest getExecuteCodeRequest(OjProblemSubmit ojProblemSubmit, OjProblem ojProblem) {

		ExecuteCodeRequest executeCodeRequest = new ExecuteCodeRequest();
		executeCodeRequest.setCode(ojProblemSubmit.getCode());
		executeCodeRequest.setLanguage(ojProblemSubmit.getLanguage());
		List<JudgeCase> judgeCaseList = JSONUtil.toList(ojProblem.getJudgeCase(), JudgeCase.class);
		List<String> inputList = judgeCaseList.stream().map(JudgeCase::getInput).collect(Collectors.toList());
		executeCodeRequest.setInputList(inputList);
		return executeCodeRequest;
	}

	private JudgeTask setJudgeTask(ExecuteCodeResponse executeCodeResponse, OjProblem ojProblem,
			OjProblemSubmit ojProblemSubmit) {
		JudgeTask judgeTask = new JudgeTask();
		judgeTask.setOjProblem(ojProblem);
		judgeTask.setOjProblemSubmit(ojProblemSubmit);
		judgeTask.setExecuteCodeResponse(executeCodeResponse);
		return judgeTask;
	}

}
